import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import Header from './components/Header/Header'
import List from './components/List/List'
import Footer from './components/Footer/Footer'
import './App.css'
export default class App extends Component {
  state = {
    // 当组件创建的时候,应该在定义状态数据时.立刻去获取缓存数据
    list: JSON.parse(localStorage.getItem('todos')) || [],
  }

  // 组件挂载
  componentDidMount() {
    // 订阅Item组件传过来的id,用来修改数据状态
    this.updateToken = PubSub.subscribe('update', (topic, id) => {
      this.update(id)
    })
    // 订阅Item组件传过来的id,用来删除数据
    this.deleteToken = PubSub.subscribe('delete', (topic, id) => {
      this.delete(id)
    })
  }

  componentWillUnmount() {
    PubSub.unsubscribe(this.updateToken)
    PubSub.unsubscribe(this.deleteToken)
  }

  //添加任务
  add = (todoName) => {
    const { list } = this.state
    // console.log(todoName)
    // 根据任务名创建新的任务对象

    const obj = {
      // 优化id: 目标就是id为整数,不能和其他数据的id重复.而且要递增
      // 思路: 每一次获取数组中最后一个,拿到最后一个的id.然后根据当前id加1计算新数据的id
      // 如果数组中有数据,则找到最后一个的id+1, 如果没有数据,新数据的id就是1
      id: list.length ? list[list.length - 1].id + 1 : 1,
      todoName,
      isDone: false,
    }
    // 将任务对象添加到数组中
    const newList = [...this.state.list]
    newList.push(obj)
    this.setState({
      list: newList,
    })
  }
  // 修改任务
  update = (id) => {
    const newList = [...this.state.list]
    // 遍历过程中,根据id找到指定数据,然后直接取反即可
    newList.forEach((item) => {
      if (item.id === id) {
        item.isDone = !item.isDone
      }
    })
    this.setState({
      list: newList,
    })
  }
  //删除一条
  delete = (id) => {
    const newList = this.state.list.filter((item) => item.id !== id)
    this.setState({
      list: newList,
    })
  }

  // 修改所有任务的状态
  updateAll = () => {
    // 1. 要计算出来,到底要把所有的数据改成true还是false

    // 如果所有的数据中,有一个的状态是false, 则接下来所有的数据,都改成true
    // 如果所有的数据中,都是true, 则接下来所有的数据,改成false

    const result = this.state.list.every((item) => item.isDone)

    // 2. 根据第一步计算结果,给每一个数据重新修改状态
    // 如果result是true,则所有数据,改成false
    // 如果reuult是false,则所有数据,改成true
    const newList = this.state.list.map((item) => {
      item.isDone = !result
      return item
    })
    this.setState({
      list: newList,
    })
  }

  // 清除所有完成项的函数
  clearAllDone = () => {
    const newList = this.state.list.filter((item) => !item.isDone)
    this.setState({
      list: newList,
    })
  }
  render() {
    // 每一次修改数据,都会调用render函数.我们可以把存储最新数据的代码,写在render里面
    localStorage.setItem('todos', JSON.stringify(this.state.list))
    return (
      <div className="todo-container">
        <div className="todo-wrap">
          {/* 把app组件中的add函数,传递给Header */}
          <Header add={this.add}></Header>
          {this.state.list.length ? (
            <div>
              <List list={this.state.list}></List>
              <Footer
                list={this.state.list}
                updateAll={this.updateAll}
                clearAllDone={this.clearAllDone}
              ></Footer>
            </div>
          ) : (
            <h1>暂无任务!</h1>
          )}
        </div>
      </div>
    )
  }
}
